using System;
using Slaks.Graphs.Algorithms.DistanceAlgorithm;
using Slaks.Graphs.GraphBuilder;

namespace Slaks.Graphs.Algorithms.ExperimentalDistances
{
	public class MCSbalancedDistance : GraphDistanceBase
	{
        public MCSbalancedDistance()
            : base()
        {
        }

        public MCSbalancedDistance(Graph one, Graph two) 
            : base ( one, two )
        {
        }
		public override bool CanOperateOnRepresentation (GraphBuilder.BuilderType builderType)
		{
			switch(builderType)
			{
			case BuilderType.StandardRepresentationSchenker:
			case BuilderType.ExtractorBuilderNodesOnly:
			case BuilderType.StandardRepresentationSlaks:
			case BuilderType.StandardSimpleRepresentationSlaks:
				return true;
				
			}
			return false;
		}
		/// <summary>
		/// MCSbalanced
		/// </summary>
		/// <param name="one"></param>
		/// <param name="two"></param>
		/// <returns></returns>
		public override double GetDistance()
		{
            double mcsRegular = new DistMCS4VertexEdgeCount(one, two).GetDistance();

			Graph maxCommonSubgraph = (one.GetMCS(two));
			double mcsEdgeCount = maxCommonSubgraph.GetEdgeCount();
			double mcsVertexCount = maxCommonSubgraph.GetVertexCount();
			double mcsCommonGraphSize = mcsEdgeCount + mcsVertexCount;

			double graphSizeOneVertexCount = one.GetVertexCount();
			double graphSizeTwoVertexCount = two.GetVertexCount();

			if (mcsCommonGraphSize > graphSizeOneVertexCount || mcsCommonGraphSize > graphSizeTwoVertexCount)
			{
				return mcsRegular;
			}
			return 1 - mcsCommonGraphSize/Math.Max(graphSizeOneVertexCount, graphSizeTwoVertexCount);
		}

	}
}